package com.zhou.bpm.service.impl;

import com.zhou.bpm.domain.dto.BpmNodeApproverDto;
import com.zhou.bpm.domain.dto.BpmNodeApproverUserDto;
import com.zhou.bpm.domain.dto.BpmNodeDto;
import com.zhou.bpm.domain.vo.NodeApproverVo;
import com.zhou.bpm.entity.BpmNode;
import com.zhou.bpm.entity.BpmNodeApprover;
import com.zhou.bpm.entity.BpmProcess;
import com.zhou.bpm.service.IBpmNodeApproverService;
import com.zhou.bpm.service.IBpmNodeService;
import com.zhou.bpm.service.IBpmProcessService;
import com.zhou.bpm.service.IProcessService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

import static com.zhou.common.Constants.APPLY;

/**
 * @Author: zhoujinchuan
 * @Description: TODO（请添加描述）
 * @CreateTime: 2023/10/25 10:08
 */
@Service
public class ProcessServiceImpl implements IProcessService {

    @Autowired
    private IBpmNodeService nodeService;

    @Autowired
    private IBpmProcessService processService;

    @Autowired
    private IBpmNodeApproverService nodeApproverService;

    @Override
    public BpmNode addProcessNode(BpmNodeDto dto) {
        //判断是否有重复的流程编码和流程节点
        BpmNode node = nodeService.lambdaQuery().eq(BpmNode::getProcessCode, dto.getProcessCode()).eq(BpmNode::getNodeCode, dto.getNodeCode()).one();
        Assert.isNull(node, "节点信息已存在");
        BpmProcess process = processService.lambdaQuery().eq(BpmProcess::getProcessCode, dto.getProcessCode()).one();
        Assert.notNull(process, "流程信息不存在");
        node = nodeService.lambdaQuery()
                .eq(BpmNode::getProcessCode, dto.getProcessCode())
                .eq(BpmNode::getOrderNum, dto.getOrderNum())
                .one();
        Assert.isNull(node, "节点顺序重复");
        BpmNode target = new BpmNode();
        BeanUtils.copyProperties(dto, target);
        Assert.isTrue(nodeService.save(target), "添加节点失败");
        return target;
    }

    @Override
    public BpmNode modifyProcessNode(BpmNodeDto dto) {
        BpmNode node = nodeService.lambdaQuery().eq(BpmNode::getProcessCode, dto.getProcessCode()).eq(BpmNode::getNodeCode, dto.getNodeCode()).one();
        Assert.notNull(node, "节点信息不存在存在");
        if (APPLY.equals(node.getNodeCode())){
            Assert.isTrue(!APPLY.equals(dto.getNodeCode()),"申请节点的nodeCode不能更改");
            Assert.isTrue(0 != dto.getOrderNum(),"申请节点的orderNum不能更改");
        }
        if (!dto.getOrderNum().equals(node.getOrderNum())) {
            BpmNode nodeOrderNum = nodeService.lambdaQuery()
                    .eq(BpmNode::getProcessCode, dto.getProcessCode())
                    .eq(BpmNode::getOrderNum, dto.getOrderNum())
                    .one();
            Assert.isNull(nodeOrderNum, "节点顺序重复");
        }
        BpmNode target = new BpmNode();
        BeanUtils.copyProperties(dto, target);
        target.setId(node.getId());
        Assert.isTrue(nodeService.updateById(target), "修改节点失败");
        return target;
    }

    @Override
    public void deleteProcessNode(String processCode, String nodeCode) {
        Assert.isTrue(APPLY.equals(nodeCode),"申请节点不能删除");
        BpmNode node = nodeService.lambdaQuery().eq(BpmNode::getProcessCode, processCode).eq(BpmNode::getNodeCode, nodeCode).one();
        Assert.notNull(node, "节点信息不存在");
        Assert.isTrue(nodeService.removeById(node.getId()), "删除节点失败");
    }

    @Override
    public List<BpmNode> listQueryProcessNode(String processCode) {
        return nodeService.lambdaQuery().eq(BpmNode::getProcessCode, processCode).orderByAsc(BpmNode::getOrderNum).list();
    }

    @Override
    public BpmNode getByProcessCodeAndNodeCode(String processCode, String nodeCode) {
        return nodeService.lambdaQuery().eq(BpmNode::getProcessCode, processCode).eq(BpmNode::getNodeCode, nodeCode).one();
    }

    @Override
    public List<NodeApproverVo> listQueryNodeApprover(String processCode, String nodeCode) {
        return nodeApproverService.getNodeApproverList(processCode,nodeCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void adjustmentNodeApprover(BpmNodeApproverDto dto) {
        String processCode = dto.getProcessCode();
        String nodeCode = dto.getNodeCode();
        BpmNode bpmNode = nodeService.lambdaQuery().eq(BpmNode::getProcessCode, processCode).eq(BpmNode::getNodeCode, nodeCode).one();
        Assert.notNull(bpmNode, processCode + "流程中不存在流程节点" + nodeCode);
        nodeApproverService.removeApprover(processCode,nodeCode);
        Integer nodeId = bpmNode.getId();
        List<BpmNodeApproverUserDto> userDtoList = dto.getUserDtoList();
        if (!CollectionUtils.isEmpty(userDtoList)) {
            List<BpmNodeApprover> bpmNodeApprovers = userDtoList.stream().map(e -> {
                BpmNodeApprover bpmNodeApprover = new BpmNodeApprover();
                bpmNodeApprover.setNodeId(nodeId);
                bpmNodeApprover.setMemberCode(e.getMemberCode());
                bpmNodeApprover.setMemberName(e.getMemberName());
                return bpmNodeApprover;
            }).collect(Collectors.toList());
            Assert.isTrue(nodeApproverService.saveBatch(bpmNodeApprovers), "设置审批人失败");
        }

    }

    @Override
    public List<BpmNode> queryProcessNodesBeforeList(String processCode, String currentNode) {
        BpmNode one = nodeService.lambdaQuery().eq(BpmNode::getProcessCode, processCode).eq(BpmNode::getNodeCode, currentNode).one();
        return nodeService.lambdaQuery().eq(BpmNode::getProcessCode, processCode).lt(BpmNode::getOrderNum, one.getOrderNum()).list();
    }
}
